#include "common.h"
#include <ShellAPI.h>
#include <codecvt>

Common::Common(void) {
    // 使用构造函数初始化可执行文件的全路径
    if (exePath.empty()) {
        TCHAR buffer[_MAX_PATH];
        GetModuleFileName(NULL, buffer, _MAX_PATH);
        exePath = buffer;
    }
}

Common::~Common(void) {}

Common &Common::getInstance() {
    static Common instance;
    return instance;
}

void Common::showMessageBox(bool error, const WString &message) {
    if (error) {
        MessageBox(NULL, message.c_str(), L"错误", MB_OK | MB_ICONERROR);
    } else {
        MessageBox(NULL, message.c_str(), L"提示", MB_OK | MB_ICONINFORMATION);
    }
}

#ifdef DEBUG
void Common::debug(const WString &message) { showMessageBox(false, message); }
#else
void Common::debug(const WString &message) {}
#endif

bool Common::isFileExists(const WString &filename) {
    DWORD const dwAttrib = GetFileAttributes(filename.c_str());
    return dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}

WString Common::getExePath() { return exePath; }

WString Common::getExeDir() {
    if (exeDir.empty()) {
        size_t lastSlash = exePath.rfind('\\');
        exeDir = exePath.substr(0, lastSlash);
    }
    return exeDir;
}

WString Common::getEnvVar(const WString &name) {
    TCHAR envVarValue[_MAX_PATH];
    if (GetEnvironmentVariable(name.c_str(), envVarValue, _MAX_PATH - 1)) {
        WString value(envVarValue);
        return value;
    }
    return L"";
}

bool Common::setEnvVar(const WString &name, const WString &value) {
    return SetEnvironmentVariable(name.c_str(), value.c_str()) ? true : false;
}

std::list<WString> Common::splitString(const WString &text, const TCHAR &delimiter) {
    std::list<WString> rtn;
    size_t from = 0;
    size_t pos = text.npos;
    while ((pos = text.find(delimiter, from)) != text.npos) {
        WString part = text.substr(from, pos - from);
        if (!part.empty()) {
            rtn.push_back(part);
        }
        from = pos + 1;
    }
    if (from + 1 < text.length()) {
        rtn.push_back(text.substr(from));
    }
    return rtn;
}

WString Common::trimString(WString &text) {
    size_t start = 0;
    size_t end = text.length();
    while (start != end) {
        wchar_t head = text[start];
        wchar_t rear = text[end - 1];
        if (head == ' ' || head == '\t' || head == '\r' || head == '\n') {
            start++;
        } else if (rear == ' ' || rear == '\t' || rear == '\r' || rear == '\n') {
            end--;
        } else {
            break;
        }
    }
    return text.substr(start, end - start);
}

const std::string Common::wstring2utf8(const WString &text) {
    std::wstring_convert<std::codecvt_utf8<wchar_t>> cvt;
    return cvt.to_bytes(text);
}

std::list<WString> Common::getCommandLineArgs() {
    int argc;
    LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
    std::list<WString> argsList;
    for (int i = 1; i < argc; i++) { // 从 1 开始跳过程序本身的名字
        argsList.push_back(WString(argv[i]));
    }
    return argsList;
}
